程式設計中資料結構
與演算法
是非常重要的兩大項目,彼此之間都會影響程式的運作。
電腦在儲存資料時,會儲存在電腦的記憶體中,而資料可以有不同的儲存與組織方式,即為資料結構。
最佳化的資料結構是能在有限的記憶體中,有組織地控制資料存放的位置或順序,並且配合適當演算法,來有效地提高運算速度。換句話說,選擇適當的資料結構能夠提高演算法的效率。
可以想像水跟書是不同種的結構,杯子與書櫃各適合放入什麼樣的結構?水倒入杯子比較方便測量,書放上書櫃比較方便排序。
不同種的資料結構適合不同的應用,一位程式設計師必須選擇一種資料結構來進行資料的新增、刪除、修改…等動作,若在選擇資料結構時作了錯誤決定,將造成程式執行上變得沒效率。
演算法被定義為一個可以用來解決某一問題的方法或算法。可以想像一份料理食譜,裡面寫著做成這份料理的步驟,這樣的概念套用到電腦領域,用特定方法來解決特定問題,就是演算法的誕生。
這樣的過程,可以用下圖來表示:
現代生活中,你的周遭就有許多演算法,像是Facebook會根據你的好友關係,給予推薦的好友;Spotify會根據你常聽的音樂類型,給予推薦的歌曲;Youtube會根據你常看的影片類型或頻道,給予相關推播;甚至我們平時常用的搜尋引擎也必須藉由不斷更新演算法來運作。
輸入(Input):
0個或是1以上的輸入。輸出(Output):
至少有一個輸出結果。明確性(Definiteness):
每個步驟或指令必須是明確的而不含糊的。有限性(Finiteness):
在有限的步驟後一定會結束,不會有無窮迴圈。有效性(Effectiveness):
每個步驟清楚具有可行性,能用紙筆來表達。複雜度可以用來衡量演算法的效率,又分為時間複雜度(Time Complexity)與空間複雜度(Space Complexity),通常會用Big O來表示。
可以說電腦執行演算法所花費的時間成本。花費的時間並非以秒
為單位計算,是以執行的次數
來做計算。
可以說是電腦執行演算法所需要耗費的記憶體空間
。
而時間複雜度和空間複雜度兩者是可以互相trade off的。
Trade off意思是在某些情況下,我們是可以讓程式多用一些記憶體空間記下一些會被重複使用的資訊,能夠省去一些重複的運算,來加速程式的執行時間;或者我們完全沒有多餘的記憶體資源可以使用,可以透過把一些原本可以靠記憶體儲存的資訊改用重複計算的方式來取得。也就是一種用空間來換取時間,用時間換取空間的概念。
O(1):
常數時間,不管你輸入多少資料,執行時間不變。O(n):
線性時間,執行時間會隨著輸入多少資料 n 等比例增加。O(n²):
平方時間,執行時間會成二次方成長。O(2^n):
指數時間,執行時間會成2的n次方成長,效能較差,盡可能避免。O(log n):
對數時間,log 8 = 3,也就是8 = 2³,執行時間一開始增加,到一定程度後無明顯增加。O(n log n):
線性對數時間,介於線性與平方之間。